﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// 上传文件
    /// </summary>
    public class HttpFile : IDisposable
    {
        /// <summary>
        /// 文件头
        /// </summary>
        public List<HeaderItem> Headers { get; internal set; }

        /// <summary>
        /// 内容类型
        /// </summary>
        public string ContentType { get; internal set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; internal set; }

        /// <summary>
        /// 文件名
        /// </summary>
        public string Filename { get; internal set; }

        /// <summary>
        /// 缓存数据
        /// </summary>
        private BufferData _bufferData = null;


        /// <summary>
        /// 构造函数
        /// </summary>
        public HttpFile()
        {

        }




        private Stream _stream = null;
        internal void BeginWriteFile(string filePath)
        {
            this._stream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            this._bufferData = new BufferData(filePath, 0, -1);
        }

        internal void BeginWriteBuffer()
        {
            this._stream = new MemoryStream();
        }

        internal void Write(byte[] buffer, int offset, int cout)
        {
            this._stream.Write(buffer, offset, cout);
            this._stream.Flush();
        }

        internal void EndWrite()
        {
            if (this._stream == null)
            {
                return;
            }

            if (this._stream is MemoryStream)
            {
                var ms = (MemoryStream)this._stream;
                byte[] buffer = ms.GetBuffer().Take((int)ms.Position).ToArray();
                this._bufferData = new BufferData(buffer);
            }
            else if (this._stream is FileStream)
            {
                this._bufferData.UpdateFileBufferLength(this._stream.Length);
            }

            this._stream.Close();
            this._stream.Dispose();
            this._stream = null;
        }



        /// <summary>
        /// 数据拷贝到目标数据流中
        /// </summary>
        /// <param name="stream">目标数据流</param>
        public void CopyTo(Stream stream)
        {
            if (this._bufferData == null)
            {
                throw new ApplicationException("内存错误，缓存数据为null");
            }

            if (this._bufferData.DataType == BufferDataType.Bytes)
            {
                stream.Write(this._bufferData.Bytes, 0, this._bufferData.Bytes.Length);
            }
            else
            {
                using (var fs = new FileStream(this._bufferData.FilePath, FileMode.Open, FileAccess.Read))
                {
                    fs.CopyTo(stream);
                }
            }
        }

        /// <summary>
        /// 数据拷贝到目标数据流中
        /// </summary>
        /// <param name="filePath">目标文件路径</param>
        public void CopyTo(string filePath)
        {
            if (this._bufferData == null)
            {
                throw new ApplicationException("内存错误，缓存数据为null");
            }

            if (this._bufferData.DataType == BufferDataType.Bytes)
            {
                using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    fs.Write(this._bufferData.Bytes, 0, this._bufferData.Bytes.Length);
                }
            }
            else
            {
                File.Move(this._bufferData.FilePath, filePath);
            }
        }




        /// <summary>
        /// Dispose
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        public void Dispose()
        {
            this._bufferData = null;

            if (this._stream != null)
            {
                this._stream.Close();
                this._stream.Dispose();
                this._stream = null;
            }
        }
    }
}
